﻿using UnityEngine;
using System.IO;
using System.Threading;
using System;
using XLua;
using Sirenix.OdinInspector;
using static UnityEditor.EditorApplication;

namespace Main
{
    [HideMonoScript]
    [RequireComponent(typeof(ComponentIDE))]
    public class HotfixMonoBehaviour : MonoBehaviour
    {
        /// <summary>
        /// XLua 环境
        /// </summary>
        LuaEnv luaEnv;
        [CSharpCallLua]
        private delegate Action IFunc();
        private IFunc iAwake;
        private IFunc iStart;
        private IFunc iEnable;
        private IFunc iDisable;
        private IFunc iUpdate;
        private IFunc iLateUpdate;
        private IFunc iFixedUpdate;
        private IFunc iDestroy;
        /// <summary>
        /// 加载热更程序集
        /// </summary>
        private void LoadHotFixAssembly()
        {
            luaEnv = new LuaEnv();
            luaEnv.AddLoader((ref string filename) =>
            {
                string path = PathConfig.AbsolutePath + PathConfig.HotfixPath + filename + ".lua";
                return File.ReadAllBytes(path);
            });

            luaEnv.DoString(" require('ECS/Game')");

            // 周期函数
            iAwake = luaEnv.Global.GetInPath<IFunc>("Game.Awake");
            iStart = luaEnv.Global.GetInPath<IFunc>("Game.Start");
            iEnable = luaEnv.Global.GetInPath<IFunc>("Game.OnEnable");
            iDisable = luaEnv.Global.GetInPath<IFunc>("Game.OnDisable");
            iUpdate = luaEnv.Global.GetInPath<IFunc>("Game.Update");
            iLateUpdate = luaEnv.Global.GetInPath<IFunc>("Game.LateUpdate");
            iFixedUpdate = luaEnv.Global.GetInPath<IFunc>("Game.FixedUpdate");
            iDestroy = luaEnv.Global.GetInPath<IFunc>("Game.OnDestroy");

            // 参数赋值
            luaEnv.Global.SetInPath<Transform>("Game.Transform", transform);
            luaEnv.Global.SetInPath<ComponentIDE>("Game.ComponentIDE", GetComponent<ComponentIDE>());
        }
        /// <summary>
        /// 卸载热更程序集
        /// </summary>
        private void UnLoadHotFixAssembly()
        {
            iAwake = null;
            iStart = null;
            iEnable = null;
            iDisable = null;
            iUpdate = null;
            iLateUpdate = null;
            iFixedUpdate = null;
            iDestroy = null;
            try
            {
                luaEnv?.Dispose();
            }
            catch (Exception e)
            {

            }
            luaEnv = null;
        }
        private void Awake()
        {
            LoadHotFixAssembly();
            iAwake?.Invoke();
        }
        private void Start()
        {
            iStart?.Invoke();
        }
        private void OnEnable()
        {
            iEnable?.Invoke();
        }
        private void OnDisable()
        {
            iDisable?.Invoke();
        }
        private void Update()
        {
            iUpdate?.Invoke();
            luaEnv.Tick();
        }
        private void LateUpdate()
        {
            iLateUpdate?.Invoke();
        }
        private void FixedUpdate()
        {
            iFixedUpdate?.Invoke();
        }
        private void OnDestroy()
        {
            iDestroy?.Invoke();
            UnLoadHotFixAssembly();
        }
    }
}